package razorpay

import (
	"bytes"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"github.com/spf13/viper"
	"github.com/wonderivan/logger"
	"io/ioutil"
	"net/http"
	"payment/app/validator"
	"payment/dao"
	"payment/model"
	"payment/utils"
)

type RzPayService struct {
	Host string
	SKID string
	SK   string
}

func GetRzPay() (rz *RzPayService) {
	return &RzPayService{
		Host: viper.GetString("razorpay.HOST"),
		SKID: viper.GetString("razorpay.SKID"),
		SK:   viper.GetString("razorpay.SK"),
	}
}

/**
创建收款支付单
*/
func (rz *RzPayService) CreateOrder(args validator.PayEntryValidator) (*model.PayEntry, error) {
	orderReq := OrderRequest{
		Amount:         args.Amount,
		Currency:       "INR",
		Receipt:        utils.GetOrderId("RZ"),
		PaymentCapture: "1", //1自动收钱
	}
	requestUrl := fmt.Sprintf("%s%s", rz.Host, "orders")
	data, err := rz.Request(requestUrl, "POST", "JSON", orderReq)
	logger.Debug("RzPayService_CreateOrder_Info | orderReq=%+v | err=%v", orderReq, err)
	razor := new(RazorCreateOrderResponse)
	err = json.Unmarshal(data, razor)
	if err != nil {
		logger.Error("RzPayService_CreateOrder_JsonUnmarshal_Err | err=%v", err)
		return nil, err
	}
	//请求成功写入流水
	pE := new(model.PayEntry)
	pE.AppId = args.AppId
	pE.PayChannel = model.RAZORPAY
	pE.AppOrderId = args.AppOrderId
	pE.OrderId = orderReq.Receipt
	pE.PaymentOrderId = razor.Id
	pE.ThirdCode = razor.Status
	pE.Status = model.PAYING
	engine, err := dao.GetMysql()
	if engine == nil || err != nil {
		logger.Error("RzPayService_CreateOrder_GetDB_Err | err=%v", err)
		return nil, err
	}
	_, err = engine.Insert(pE)
	if err != nil {
		logger.Error("RzPayService_CreateOrder_InsertDB_Err | err=%v", err)
	}
	return pE, err
}

/**
 * 查询订单状态
 *
{
	"id": "order_EPhIvAjVwIqqpL",
	"entity": "order",
	"amount": 50000,
	"amount_paid": 0,
	"amount_due": 50000,
	"currency": "INR",
	"receipt": "order_test1123213123",
	"offer_id": null,
	"status": "attempted",
	"attempts": 1,
	"notes": [],
	"created_at": 1583664618
}
 * param: string orderId
 * return: interface{}
 * return: error
*/
func (rz *RzPayService) Inquiry(paymentId string, orderId string) (status model.PayStatus, err error) {
	requestUrl := fmt.Sprintf("%s%s/%s", rz.Host, "payments", paymentId)
	data, err := rz.Request(requestUrl, "GET", "", nil)
	logger.Debug("RzPayService_Inquiry_Info | orderReq=%+v | err=%v | data=%v", paymentId, err, string(data))
	if err != nil {
		return model.PAYING, err
	}
	paymentEntity := new(model.RazorPaymentEntity)
	err = json.Unmarshal(data, paymentEntity)
	if err != nil {
		logger.Error("PayEntryService_Inquiry_JsonUnmarshal | err=%v | paymentId=%+v", err, paymentId)
		return "", err
	}
	if paymentEntity.Status == model.Captured {
		return model.PAYSUCCESS, nil
	}
	if paymentEntity.Status == model.Failed {
		return model.PAYFAILD, nil
	}
	return model.PAYING, err
}

/**
付钱 TODO
*/
func (rz *RzPayService) Payment() {

}

/**
统一请求
*/
func (rz *RzPayService) Request(url string, method string, contentType string, sendData interface{}) (res []byte, err error) {
	client := &http.Client{}
	var data []byte
	if contentType == "JSON" {
		data, _ = json.Marshal(sendData)
	} else if sendData != nil {
		data = sendData.([]byte)
	}
	//提交请求
	req, err := http.NewRequest(method, url, bytes.NewBuffer(data))
	if err != nil {
		logger.Error("RzPayService_create_order | err=%+v | req=%+v", err, sendData)
		return
	}
	input := fmt.Sprintf("%s:%s", rz.SKID, rz.SK)
	authKey := base64.StdEncoding.EncodeToString([]byte(input))
	header := map[string][]string{
		"Content-Type":  {"application/json;charset=utf-8"},
		"Authorization": {"Basic " + authKey},
	}
	req.Header = http.Header(header)

	//处理返回结果
	response, err := client.Do(req)
	if err != nil {
		logger.Error("RzPayService_request_err | err=%+v | req=%+v", err, sendData)
		return
	}
	body, err := ioutil.ReadAll(response.Body)
	if err != nil {
		logger.Error("RzPayService_response_read_err | err=%+v | req=%+v", err, sendData)
		return
	}
	defer func() {
		_ = response.Body.Close()
	}()
	return body, nil
}
